#include <glib.h>

struct proc_data
{
    const gchar *proc_path;
    const gchar *proc_param;
};

static gpointer td_spawn_sync_multi_thread_instance (gpointer data)
{
    GError *error = NULL;
    GPtrArray *argv;
    char *stdout_str;
    char *stderr_str;
    int estatus;

    struct proc_data *pdata = (struct proc_data *) (data);
    g_return_val_if_fail((NULL != data), NULL);

    argv = g_ptr_array_new ();
    g_ptr_array_add (argv, (gpointer)pdata->proc_path);
    g_ptr_array_add (argv, (gpointer)pdata->proc_param);
    g_ptr_array_add (argv, NULL);

    g_printf("before spawn sync [%s %s]======================= \n", pdata->proc_path, pdata->proc_param);
    g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &stdout_str, &stderr_str, &estatus, &error);
    g_assert_no_error (error);
    g_printf("stdout_str=\n%s \n", stdout_str);
    g_printf("stderr_str=\n%s \n", stderr_str);
    g_printf("after spawn sync [%s %s]======================= \n", pdata->proc_path, pdata->proc_param);

    g_free (stdout_str);
    g_free (stderr_str);
    g_ptr_array_free (argv, TRUE);

    gchar c = (char)(pdata->proc_param[strlen(pdata->proc_param)-1]);
    g_printf("c=%c \n", c);

    return GINT_TO_POINTER (c);
}

static void td_multithreaded_test_single_run (GThread **thread, GThreadFunc function, struct proc_data *pdata)
{
    g_return_if_fail(NULL != pdata);
    g_return_if_fail(NULL != thread);
    g_printf("path=%s param=%s\n", pdata->proc_path, pdata->proc_param);

    *thread = g_thread_new(pdata->proc_path, function, (gpointer)pdata);
    g_return_if_fail(NULL != thread);

}

static void td_spawn_sync_multi_thread (void)
{
    GThread *thd1, *thd2, *thd3, *thd4;
    gpointer ret1, ret2, ret3, ret4;

    struct proc_data pdata1 = {"/bin/ls", "-a"};
    td_multithreaded_test_single_run(&thd1, td_spawn_sync_multi_thread_instance, &pdata1);

    struct proc_data pdata2 = {"/usr/bin/sleep", "2"};
    td_multithreaded_test_single_run(&thd2, td_spawn_sync_multi_thread_instance, &pdata2);

    struct proc_data pdata3 = {"/usr/bin/top", "-n 3"};
    td_multithreaded_test_single_run(&thd3, td_spawn_sync_multi_thread_instance, &pdata3);

    struct proc_data pdata4 = {"/bin/echo", "hello world"};
    td_multithreaded_test_single_run(&thd4, td_spawn_sync_multi_thread_instance, &pdata4);

    ret1 = g_thread_join(thd1);
    ret2 = g_thread_join(thd2);
    ret3 = g_thread_join(thd3);
    ret4 = g_thread_join(thd4);

    g_printf("ret1=%c ret2=%c ret3=%c ret4=%c \n", ret1 ,ret2, ret3, ret4);

    return;
}

gint main (gint argc, gchar *argv[])
{
    gint ret;

    g_test_init (&argc, &argv, NULL);

    g_test_add_func ("/gthread/spawn-sync", td_spawn_sync_multi_thread);

    ret = g_test_run();

    return ret;
}
